package com.dayuanit.dy15.atm.filter;

import com.alibaba.fastjson.JSON;
import com.dayuanit.dy15.atm.dto.ResponseDTO;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * 过滤掉非法的请求，比如，在未登录的情况下，用户访问系统中受保护的URL地址。
 *
 * 我们要解决两个问题：
 * 1.怎么判断用户是否登录？
 * 2.哪些地址是受保护的？
 */
public class LoginFilter implements Filter {
    public LoginFilter() {
        System.out.println(">>>>>>>>LoginFilter()<<<<<<<<<");
    }

    //存放不受保护的URL地址
    private static List<String> unProtectedUrl;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println(">>>>>>>>>>>> LoginFilter init() <<<<<<<<<<<<<");

        //获取白名单文件的路径
        String whiteFileName = filterConfig.getInitParameter("WhiteList");
        //atm/whiteList.properties
        InputStream resourceAsStream = LoginFilter.class.getClassLoader().getResourceAsStream(whiteFileName);
        Properties properties = new Properties();
        try {
            properties.load(resourceAsStream);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String urls = properties.getProperty("white.urls");
        System.out.println("urls=" + urls);

        String[] split = urls.split(",");
        //面试题：将数组转为集合  集合转数组
        unProtectedUrl = Arrays.asList(split);

        String username = filterConfig.getInitParameter("username");
        System.out.println("username=" + username);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println(">>>>>>>> LoginFilter begin <<<<<<<<<<<<<");

//        怎么判断用户是否登录？
//        servletRequest.getse
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;

        //传入false，如果能通过jessionID找到session对象，则返回；反之，就返回null.
        HttpSession session = request.getSession(false);

        String requestURI = request.getRequestURI();

//        2.哪些地址是受保护的？

        //只要没登录 并且访问的地址不在unProtectedUrl集合中就挡回去
        if (null == session || null == session.getAttribute("loginUser")) {
            //不在集合中的地址就是受保护的
            if (!unProtectedUrl.contains(requestURI)) {
                System.out.println("未登录");

                //当用户没有登录，返回信息要分情况；
                //1。当前请求是异步的，也就ajax请求，则响应一个json串；
                //2.当前请求是非异步的，则重定向到登录页面

                String ajaxHeader = request.getHeader("X-Requested-With");
                if (StringUtils.isNotBlank(ajaxHeader)) {
                    try {
                        response.setContentType("application/json; charset=utf-8");
                        ServletOutputStream outputStream = response.getOutputStream();

                        outputStream.write(JSON.toJSONString(ResponseDTO.unLogin("请登录")).getBytes("utf-8"));
                        outputStream.flush();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return;
                }

                //重定向，原理：后台响应302状态码，终端看到是302,则在响应头获取location的值，
                //location的值就是重定向的地址，终端获取到地址后，二话不说就再次发送这个请求。
                response.sendRedirect("/");
                return;
            }
        }


        //将请求继续向下传递。
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println(">>>>>>>> LoginFilter end <<<<<<<<<<<<<");
    }

    @Override
    public void destroy() {

    }
}
